package com.fengchao.api.service;

import com.alibaba.fastjson.JSON;
import com.fengchao.api.config.Constant;
import com.fengchao.api.dao.bci.BciArtistInfoMapper;
import com.fengchao.api.dao.bci.BciFieldInfoMapper;
import com.fengchao.api.dao.bci.BciOrganizerInfoMapper;
import com.fengchao.api.dao.sam.SamArtistMessageMapper;
import com.fengchao.api.dao.usr.*;
import com.fengchao.model.bci.BciArtistInfo;
import com.fengchao.model.bci.BciFieldInfo;
import com.fengchao.model.bci.BciOrganizerInfo;
import com.fengchao.model.entity.comm.CustomBizException;
import com.fengchao.model.entity.comm.Message;
import com.fengchao.model.entity.comm.ResponseParameter;
import com.fengchao.model.entity.comm.TokenException;
import com.fengchao.model.usr.*;
import com.fengchao.util.common.CommonValidator;
import com.fengchao.util.common.DateUtil;
import com.fengchao.util.common.SmsTools;
import com.fengchao.util.common.UpyunTools;
import com.fengchao.util.encrypt.Md5;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import java.util.*;

import static com.fengchao.api.config.Constant.*;

/**
 * 用户服务
 * Created by wangnian on 2016/6/3.
 */
@Service
public class UsrService {

    private static Logger logger = LoggerFactory.getLogger(UsrService.class);

    @Autowired
    private UsrInfoMapper usrInfoMapper;
    @Autowired
    private UsrAppDeviceMapper usrAppDeviceMapper;
    @Autowired
    private UsrAppDeviceUserMapper usrAppDeviceUserMapper;
    @Autowired
    private UsrWebUserTokenMapper usrWebUserTokenMapper;
    @Autowired
    private UsrAppChannelMapper usrAppChannelMapper;
    @Autowired
    private UsrDeviceChannelJoinMapper usrDeviceChannelJoinMapper;
    @Autowired
    private UpyunTools upyunTools;
    @Autowired
    private UsrUserFavoriteMapper usrUserFavoriteMapper;
    @Autowired
    private SmsTools smsTools;
    @Autowired
    private UsrSendSmsLogMapper usrSendSmsLogMapper;
    @Autowired
    private UsrUserFocusArtistMapper usrUserFocusArtistMapper;
    @Autowired
    private UsrDeliveryAddressMapper usrDeliveryAddressMapper;
    @Autowired
    private UsrThirdpartAccountInfoMapper usrThirdpartAccountInfoMapper;
    @Autowired
    private BciArtistInfoMapper bciArtistInfoMapper;
    @Autowired
    private BciOrganizerInfoMapper bciOrganizerInfoMapper;
    @Autowired
    private UsrSharedMessageOptInMapper usrSharedMessageOptInMapper;
    @Autowired
    private UsrPersonalMessageMapper usrPersonalMessageMapper;
    @Autowired
    private SamArtistMessageMapper samArtistMessageMapper;
    @Autowired
    private BciService bciService;
    @Autowired
    private UsrTicketInspectorMapper usrTicketInspectorMapper;
    @Autowired
    private UsrWechatMapper usrWechatMapper;

    /**
     * 获取用户UserId
     * 成功返回userID 失败返回 null
     *
     * @param type
     * @param token
     * @param isMust
     * @return
     */
    public Integer getUserId(String type, String token, boolean isMust) {
        Integer userId = null;
        if (CommonValidator.isStringsNotNull(type, token)) {
            userId = findUserId(type, token);
        }
        if (isMust) {//如果必须登陆
            if (userId == null) {
                throw new TokenException(TOKEN_INVALID);
            }
        }
        logger.info("UserId:{}", userId);
        return userId;
    }

    /**
     * 根据type和token查询UserId
     *
     * @param type
     * @param token
     * @return
     */
    public Integer findUserId(String type, String token) {
        if (Constant.APP.equals(type)) {//APP访问
            UsrAppDeviceUser usrAppDeviceUser = usrAppDeviceUserMapper.findByAccessToken(token);
            if (usrAppDeviceUser == null) {//查询token是否存在
                logger.info("token不存在  type:{},token:{}", type, token);
                return null;
            }
            if (!usrAppDeviceUser.getIsUsable()) {//token是否有效
                logger.info("tokenIsUsable无效  type:{},token:{}", type, token);
                return null;
            }
            //token是否在有效期之内
            Date date = new Date();
            Date date1 = DateUtil.addDay(usrAppDeviceUser.getValidTime(), Integer.valueOf(CONFIGMAP.get("appOverdue")));
            if (date.compareTo(date1) > 0) {//当前时间已超过 有效开始时间+有效天数
                logger.info("token超过有效期 currentDate:{},day:{},validTime:{},date1:{}", DateUtil.parseToString(date), CONFIGMAP.get("appOverdue"), DateUtil.parseToString(usrAppDeviceUser.getValidTime()), DateUtil.parseToString(date1));
                return null;
            }
            return usrAppDeviceUser.getUserId();
        } else if (Constant.WEB.equals(type)) {
            UsrWebUserToken usrWebUserToken = usrWebUserTokenMapper.findByAccessToken(token);
            if (usrWebUserToken == null) {//查询token是否存在
                logger.info("token不存在  type:{},token:{}", type, token);
                return null;
            }
            if (!usrWebUserToken.getIsUsable()) {//token是否有效
                logger.info("tokenIsUsable无效  type:{},token:{}", type, token);
                return null;
            }
            //token是否在有效期之内
            Date date = new Date();
            Date date1 = DateUtil.addDay(usrWebUserToken.getValidTime(), Integer.valueOf(CONFIGMAP.get("webOverdue")));
            if (date.compareTo(date1) > 0) {//当前时间已超过 有效开始时间+有效天数
                logger.info("token超过有效期 currentDate:{},day:{},validTime:{},date1:{}", DateUtil.parseToString(date), CONFIGMAP.get("appOverdue"), DateUtil.parseToString(usrWebUserToken.getValidTime()), DateUtil.parseToString(date1));
                return null;
            }
            return usrWebUserToken.getUserId();
        } else {
            logger.info("type无效  type:{},token:{}", type, token);
            return null;
        }
    }

    /**
     * 保存用户信息
     *
     * @param source
     * @param channel
     * @param lastAccessIp
     * @return
     */
    @Transactional
    public UsrInfo saveUsrInfo(String mobile, String nickName, String sex, String headIcon, String password, String source, String channel, String lastAccessIp) {
        UsrInfo usrInfo = new UsrInfo();
        usrInfo.setNickname(nickName);
        usrInfo.setMobile(mobile);
        usrInfo.setPassword(Md5.encoderToString(password, Constant.MD5_KEY));
        usrInfo.setSource(source);
        usrInfo.setSex(sex);
        usrInfo.setHeadIcon(headIcon);
        usrInfo.setChannel(channel);
        usrInfo.setUserType(Constant.FANS);
        usrInfo.setLastAccessIp(lastAccessIp);
        usrInfo.setStatus(ENABLED);
        usrInfo.setCreateTime(new Date());
        usrInfoMapper.insertSelective(usrInfo);
        return usrInfo;
    }


    public UsrAppDevice findBydeviceUniqueToken(String deviceUniqueToken) {
        UsrAppDevice usrAppDevice = usrAppDeviceMapper.findByDeviceUniqueToken(deviceUniqueToken);
        return usrAppDevice;
    }

    @Transactional
    public UsrAppDevice recordDevice(String deviceType, String deviceUniqueToken, String deviceModel, String deviceSystem) {
        UsrAppDevice usrAppDevice = new UsrAppDevice();
        usrAppDevice.setDeviceType(deviceType);
        usrAppDevice.setDeviceUniqueToken(deviceUniqueToken);
        usrAppDevice.setDeviceModel(deviceModel);
        usrAppDevice.setDeviceSystem(deviceSystem);
        usrAppDevice.setCreateTime(new Date());
        Integer count = usrAppDeviceMapper.insertSelective(usrAppDevice);
        if (count > 0) {
            return usrAppDevice;
        } else {
            return null;
        }

    }

    @Transactional
    public boolean recordChannel(String channelCode, Integer deviceId) {
        UsrAppChannel usrAppChannel = usrAppChannelMapper.findByChannelCode(channelCode);
        UsrDeviceChannelJoin usrDeviceChannelJoin = new UsrDeviceChannelJoin();
        usrDeviceChannelJoin.setIsUsable(true);
        usrDeviceChannelJoin.setChannelId(usrAppChannel != null ? usrAppChannel.getId() : null);
        usrDeviceChannelJoin.setCreateTime(new Date());
        usrDeviceChannelJoin.setDeviceId(deviceId);
        usrDeviceChannelJoin.setUpdateTime(new Date());
        Integer count = usrDeviceChannelJoinMapper.insertSelective(usrDeviceChannelJoin);
        if (count > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Transactional
    public ResponseParameter register(String type, String messageToken, String deviceUniqueToken, String deviceCode, String mobile, String password, String source, String channel, String lastAccessIp) {
        ResponseParameter responseParameter = new ResponseParameter();
        //查询手机号是否存在
        UsrInfo usrInfo = usrInfoMapper.findByMobile(mobile);
        if (usrInfo == null) {
            usrInfo = saveUsrInfo(mobile, null, null, null, password, source, channel, lastAccessIp);
            if (usrInfo.getId() != null) {
                responseParameter.setStatus(Message.SUCCESS);
                responseParameter.setMessage(REGISTER_SUCCESS);
                //生成token
                String token = createToken(type, deviceUniqueToken, usrInfo.getId(), messageToken, deviceCode);
                HashMap<Object, Object> map = new HashMap<>();
                map.put("token", token);
                responseParameter.setData(map);
                return responseParameter;
            } else {
                responseParameter.setStatus(Message.FAILURE);
                responseParameter.setMessage(REGISTER_FAILURE);
                return responseParameter;
            }
        } else {
            responseParameter.setStatus(Message.FAILURE);
            responseParameter.setMessage(ALREADY_REGISTER);
            return responseParameter;
        }
    }

    @Transactional
    public ResponseParameter login(String mobile, String password, String lastAccessIp, String type, String deviceUniqueToken, String messageToken, String deviceCode) {
        //响应对象
        ResponseParameter responseParameter = new ResponseParameter();
        //业务
        UsrInfo usrInfo = usrInfoMapper.findByMobile(mobile);
        if (usrInfo == null) {//为空
            responseParameter.setStatus(Message.FAILURE);
            responseParameter.setMessage(NO_REGISTER);
            return responseParameter;
        }
        if (!Md5.encoderToString(password, Constant.MD5_KEY).equals(usrInfo.getPassword())) {//密码错误
            responseParameter.setStatus(Message.FAILURE);
            responseParameter.setMessage(PASSWORD_INVALID);
            return responseParameter;
        }
        if (usrInfo.getStatus() == Constant.DISABLE) {//用户不可用
            responseParameter.setStatus(Message.FAILURE);
            responseParameter.setMessage(USER_LOCK);
            return responseParameter;
        }
        responseParameter.setStatus(Message.SUCCESS);
        responseParameter.setMessage(LOGIN_SUCCESS);

        //更新访问ip
        UsrInfo usrInfo1 = new UsrInfo();
        usrInfo1.setId(usrInfo.getId());
        usrInfo1.setLastAccessIp(lastAccessIp);
        usrInfoMapper.updateByPrimaryKeySelective(usrInfo1);
        //生成token
        String token = createToken(type, deviceUniqueToken, usrInfo.getId(), messageToken, deviceCode);
        HashMap<Object, Object> map = new HashMap<>();
        map.put("token", token);
        responseParameter.setData(map);
        return responseParameter;
    }

    /**
     * 生成token
     *
     * @param type
     * @param deviceUniqueToken
     * @param userId
     * @param messageToken
     * @param deviceCode
     * @return
     */
    @Transactional
    public String createToken(String type, String deviceUniqueToken, Integer userId, String messageToken, String deviceCode) {
        //生成token
        Map<Object, Object> map = new HashMap<>();
        String uuid = UUID.randomUUID().toString();
        if (Constant.APP.equals(type)) {//APP访问
            UsrAppDevice usrAppDevice = usrAppDeviceMapper.findByDeviceUniqueToken(deviceUniqueToken);
            //APP  token和user的关系
            UsrAppDeviceUser usrAppDeviceUser = new UsrAppDeviceUser();
            usrAppDeviceUser.setDeviceId(usrAppDevice != null ? usrAppDevice.getId() : null);
            usrAppDeviceUser.setCreateTime(new Date());
            usrAppDeviceUser.setUserId(userId);
            usrAppDeviceUser.setAccessToken(uuid);
            usrAppDeviceUser.setMessageToken(messageToken);
            usrAppDeviceUser.setIsUsable(true);
            usrAppDeviceUser.setValidTime(new Date());
            usrAppDeviceUserMapper.insertSelective(usrAppDeviceUser);
        } else {//WEB访问
            UsrWebUserToken usrWebUserToken = new UsrWebUserToken();
            usrWebUserToken.setAccessToken(uuid);
            usrWebUserToken.setValidTime(new Date());
            usrWebUserToken.setIsUsable(true);
            usrWebUserToken.setUserId(userId);
            usrWebUserToken.setCreateTime(new Date());
            usrWebUserToken.setDeviceCode(deviceCode);
            usrWebUserTokenMapper.insertSelective(usrWebUserToken);
        }
        return uuid;
    }

    @Transactional
    public ResponseParameter updateUerInfo(UsrInfo usrInfo) {
        ResponseParameter responseParameter = new ResponseParameter(Message.FAILURE, UPDATATE_FAILURE);
        usrInfo.setUpdateTime(new Date());
        Integer count = usrInfoMapper.updateByPrimaryKeySelective(usrInfo);
        if (count > 0) {
            responseParameter.setStatus(Message.SUCCESS);
            responseParameter.setMessage(UPDATATE_SUCCESS);
            return responseParameter;
        }
        return responseParameter;
    }


    public UsrInfo findMobile(String moblie) {
        return usrInfoMapper.findByMobile(moblie);
    }


    public UsrInfo findUsrInfo(Integer userId) {
        return usrInfoMapper.selectByPrimaryKey(userId);
    }

    @Transactional
    public String uploadHeadIcon(Integer userId, MultipartFile file) {
        try {
            byte[] bytes = file.getBytes();
            String fileName = userId + new Date().getTime() + upyunTools.suffix(file.getOriginalFilename());
            String location = upyunTools.upload(Constant.CONFIGMAP.get("usr.user_icon") + fileName, bytes);
            return location;
        } catch (Exception ex) {
            logger.error("上传头像异常:{}", ex);
        }
        return "";
    }

    @Transactional
    public String uploadHeadIcon(Integer userId, StringBuffer base64Str) {
        try {
            String imgBase64 = base64Str.substring(base64Str.indexOf(",") + 1);
            byte[] bytes = new BASE64Decoder().decodeBuffer(imgBase64);
            String fileName = userId + new Date().getTime() + ".png";
            String location = upyunTools.upload(Constant.CONFIGMAP.get("usr.user_icon") + fileName, bytes);
            return location;
        } catch (Exception ex) {
            logger.error("base64Str上传头像异常:{}", ex);
        }
        return "";
    }


    public List<UsrUserFavorite> findUsrUserFavoriteByTypeUserIdForeignId(String favoriteType, Integer userId, Integer foreignId) {
        return usrUserFavoriteMapper.findUsrUserFavoriteByTypeUserIdForeignId(favoriteType, userId, foreignId);
    }

    @Transactional
    public boolean updateFavorite(String favoriteType, Integer foreignId, Integer operationType, Integer userId) {
        if (operationType == 0) {//取消收藏
            Integer count = usrUserFavoriteMapper.deleteUsrUserFavoriteByTypeUserIdForeignId(favoriteType, userId, foreignId);
            if (count > 0) {
                return true;
            }
        } else {//收藏
            List<UsrUserFavorite> usrUserFavorites = usrUserFavoriteMapper.findUsrUserFavoriteByTypeUserIdForeignId(favoriteType, userId, foreignId);
            if (usrUserFavorites.size() == 0) {
                UsrUserFavorite usrUserFavorite = new UsrUserFavorite();
                usrUserFavorite.setCreateTime(new Date());
                usrUserFavorite.setForeignId(foreignId);
                usrUserFavorite.setType(favoriteType);
                usrUserFavorite.setUserId(userId);
                Integer count = usrUserFavoriteMapper.insertSelective(usrUserFavorite);
                if (count > 0) {
                    return true;
                }
            } else {
                return true;
            }
        }
        return false;
    }

    /**
     * 修改关注
     *
     * @param artistId
     * @param userId
     * @param operationType
     * @return
     */
    @Transactional
    public boolean updateFocus(Integer artistId, Integer userId, Integer operationType) {
        if (operationType == 0) {//取消关注
            Integer count = usrUserFocusArtistMapper.delectFocus(artistId, userId);
            if (count > 0) {
                return true;
            }
        } else {//关注
            Integer count = usrUserFocusArtistMapper.findCountByArtistId(artistId, userId);
            if (count == 0) {
                UsrUserFocusArtist usrUserFocusArtist = new UsrUserFocusArtist();
                usrUserFocusArtist.setUserId(userId);
                usrUserFocusArtist.setArtistId(artistId);
                usrUserFocusArtist.setCreateTime(new Date());
                Integer count1 = usrUserFocusArtistMapper.insertSelective(usrUserFocusArtist);
                if (count1 > 0) {
                    return true;
                }
            } else {
                return true;
            }
        }
        return false;
    }

    /**
     * 发送短信
     *
     * @param phone
     * @param templateId
     * @return
     */
    public ResponseParameter sendSms(String phone, String templateId) {
        ResponseParameter responseParameter = new ResponseParameter(Message.SUCCESS, SEND_SUCCESS);
        HashMap<Object, Object> map = new HashMap<>();
        //根据手机号查询状态为最新的短信记录
        UsrSendSmsLog usrSendSmsLog = usrSendSmsLogMapper.findUsrSendSmsLogByMobile(phone);
        Integer smsMinute = Integer.parseInt(Constant.CONFIGMAP.get("smsMinute"));
        if (usrSendSmsLog != null) {
            //判断时间是否过期
            Date date = usrSendSmsLog.getCreateTime();
            Date endDate = DateUtil.addMinutes(date, Integer.valueOf(smsMinute));
            Long differDate = DateUtil.computeTimestamp(endDate, new Date());
            Long differMinute = differDate / 1000;
            if (differMinute > 1) {
                map.put("endTime", differMinute);
                responseParameter.setData(map);
                return responseParameter;
            }
        }
        String captcha = smsTools.createCaptcha();//生成验证码
        boolean bool = smsTools.sendSms(phone, templateId, captcha, smsMinute.toString());
        if (bool) {
            saveUsrSendSmsLog(phone, captcha);
            map.put("endTime", smsMinute * 60);
            responseParameter.setData(map);
            return responseParameter;
        }
        responseParameter = new ResponseParameter(Message.FAILURE, SEND_FAILURE);
        return responseParameter;
    }

    /**
     * 判断短信
     *
     * @param phone
     * @param captcha
     * @return
     */
    public boolean checkSms(String phone, String captcha) {
        //根据手机号查询状态为最新的短信记录
        UsrSendSmsLog usrSendSmsLog = usrSendSmsLogMapper.findUsrSendSmsLogByMobile(phone);
        Integer smsMinute = Integer.parseInt(Constant.CONFIGMAP.get("smsMinute"));
        if (usrSendSmsLog != null) {
            if (captcha.equals(usrSendSmsLog.getValidCode())) {
                //判断时间是否过期
                Date date = usrSendSmsLog.getCreateTime();
                Date endDate = DateUtil.addMinutes(date, Integer.valueOf(smsMinute));
                Long differDate = DateUtil.computeTimestamp(endDate, new Date());
                Long differMinute = differDate / 1000;
                if (differMinute > 1) {
                    usrSendSmsLogMapper.updateUsrSendSmsLogIsNewByMobile(phone);
                    return true;
                }
            }
        }
        logger.info("验证码验证失败:phone:{},captcha:{},smsLog:{}", phone, captcha, JSON.toJSON(usrSendSmsLog));
        return false;
    }


    /**
     * 获取地址
     *
     * @param userId
     * @return
     */
    public List<Map<String, Object>> getAddressList(Integer userId) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<UsrDeliveryAddress> list = usrDeliveryAddressMapper.findUsrDeliveryAddressByUserId(userId, null);
        for (UsrDeliveryAddress usrDeliveryAddress : list) {
            Map<String, Object> map = new HashMap<>();
            map.put("addressId", usrDeliveryAddress.getId());//地址id
            map.put("person", usrDeliveryAddress.getDeliveryPerson());//收货人
            map.put("mobile", usrDeliveryAddress.getDeliveryMobile()); //收货人手机号
            map.put("zipCode", usrDeliveryAddress.getZipCode());//邮编
            map.put("address", usrDeliveryAddress.getDeliveryAddress());//收货地址
            map.put("isDefault", usrDeliveryAddress.getIsDefault() ? 1 : 0);//是否默认
            map.put("province", usrDeliveryAddress.getProvince());//省
            map.put("city", usrDeliveryAddress.getCity());//市
            map.put("district", usrDeliveryAddress.getDistrict());//区
            map.put("road", usrDeliveryAddress.getRoad());//道路
            map.put("other", usrDeliveryAddress.getOther());//剩余部分地址
            resultList.add(map);
        }
        return resultList;
    }

    /**
     * 设置地址为默认
     *
     * @param userId
     * @param addressId
     * @return
     */
    @Transactional
    public boolean setAddressDefulet(Integer userId, Integer addressId) {
        //重置userId的默认地址
        usrDeliveryAddressMapper.updateUsrDeliveryAddressDefault(userId, false, null);
        //设置默认地址
        Integer count = usrDeliveryAddressMapper.updateUsrDeliveryAddressDefault(userId, true, addressId);
        if (count > 0) {
            return true;
        }
        return false;
    }


    /**
     * 删除地址1
     *
     * @param userId
     * @param addressId
     * @return
     */
    @Transactional
    public boolean delectAddress(Integer userId, Integer addressId) {
        Integer count = usrDeliveryAddressMapper.delectUsrDeliveryAddress(userId, addressId);
        if (count > 0) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * 添加地址
     *
     * @param userId
     * @param person
     * @param mobile
     * @param province
     * @param city
     * @param district
     * @param other
     * @param isDefault
     * @return
     */
    @Transactional
    public Integer addAddress(Integer userId, String person, String mobile, String province, String city, String district, String other, Integer isDefault) {
        //判断该用户是否已添加10个地址
        List<UsrDeliveryAddress> lists1 = usrDeliveryAddressMapper.findUsrDeliveryAddressByUserId(userId, null);
        if (lists1.size() >= 10) {
            return null;
        }
        UsrDeliveryAddress usrDeliveryAddress = new UsrDeliveryAddress();
        usrDeliveryAddress.setNation("中国");
        usrDeliveryAddress.setProvince(province);//省
        usrDeliveryAddress.setCity(city);//市
        usrDeliveryAddress.setDistrict(district);//区
        usrDeliveryAddress.setOther(other);//剩余地址
        usrDeliveryAddress.setCreateTime(new Date());
        usrDeliveryAddress.setUserId(userId);
        usrDeliveryAddress.setDeliveryPerson(person);//收件人
        usrDeliveryAddress.setDeliveryMobile(mobile);//收件人手机号
        usrDeliveryAddress.setDeliveryAddress(province + city + district + other);//收件人地址
        //如果用户添加地址时默认指定为默认地址
        if (isDefault == 1) {
            //重置userId的默认地址
            usrDeliveryAddressMapper.updateUsrDeliveryAddressDefault(userId, false, null);
            usrDeliveryAddress.setIsDefault(true);
        } else {
            //如果没有该用户没有默认收货地址将该地址设置默认的
            List<UsrDeliveryAddress> lists = usrDeliveryAddressMapper.findUsrDeliveryAddressByUserId(userId, true);
            if (lists.size() == 0) {
                usrDeliveryAddress.setIsDefault(true);
            }
        }
        Integer count = usrDeliveryAddressMapper.insertSelective(usrDeliveryAddress);
        if (count > 0) {
            return usrDeliveryAddress.getId();
        }
        return null;
    }


    /**
     * 更新地址
     *
     * @param userId
     * @param addressId
     * @param person
     * @param mobile
     * @param province
     * @param city
     * @param district
     * @param other
     * @param isDefault
     * @return
     */
    @Transactional
    public boolean updateAddress(Integer userId, Integer addressId, String person, String mobile, String province, String city, String district, String other, Integer isDefault) {
        //根据addressId查询地址
        UsrDeliveryAddress usrDeliveryAddress1 = usrDeliveryAddressMapper.selectByPrimaryKey(addressId);
        if (usrDeliveryAddress1 != null && usrDeliveryAddress1.getUserId().equals(userId)) {//判断是否是该用户的地址
            UsrDeliveryAddress usrDeliveryAddress = new UsrDeliveryAddress();
            usrDeliveryAddress.setId(addressId);
            usrDeliveryAddress.setProvince(province);//省
            usrDeliveryAddress.setCity(city);//市
            usrDeliveryAddress.setDistrict(district);//区
            usrDeliveryAddress.setOther(other);//剩余地址
            usrDeliveryAddress.setDeliveryPerson(person);//收件人
            usrDeliveryAddress.setDeliveryMobile(mobile);//收件人手机号
            usrDeliveryAddress.setDeliveryAddress(province + city + district + other);//收件人地址
            //如果用户添加地址时默认指定为默认地址
            if (isDefault == 1) {
                //重置userId的默认地址
                usrDeliveryAddressMapper.updateUsrDeliveryAddressDefault(userId, false, null);
                usrDeliveryAddress.setIsDefault(true);
            }
            Integer count = usrDeliveryAddressMapper.updateByPrimaryKeySelective(usrDeliveryAddress);
            if (count > 0) {
                return true;
            }
        }
        return false;
    }


    /**
     * 获取user信息
     *
     * @param userId
     * @return
     */
    public Map<String, Object> getUserInfo(Integer userId) {
        UsrInfo usrInfo = usrInfoMapper.selectByPrimaryKey(userId);
        //艺人信息
        Map<String, Object> map = new HashMap<>();
        if (userId == null) {
            logger.warn("userId不存在= userId:{}", userId);
            throw new CustomBizException("没有该用户");
        }
        map.put("mobile", usrInfo.getMobile());
        map.put("sex", usrInfo.getSex() == null ? "" : usrInfo.getSex());
        map.put("nickname", usrInfo.getNicknameToEmoji() == null ? usrInfo.getMobile() : usrInfo.getNicknameToEmoji());
        map.put("headIcon", usrInfo.getHeadIcon() == null ? "" : usrInfo.getHeadIcon());
        map.put("user_type", usrInfo.getUserType() == null ? "" : usrInfo.getUserType());
        map.put("personalSignature", usrInfo.getPersonalSignatureToEmoji() == null ? "" : usrInfo.getPersonalSignatureToEmoji());//个人签名
        map.put("city", usrInfo.getDefaultCity() == null ? "" : usrInfo.getDefaultCity());
        map.put("style", usrInfo.getFavouriteSongStyle() == null ? "" : usrInfo.getFavouriteSongStyle());//曲风
        //如果是主办方
        if (Constant.ORGANIZER.equals(usrInfo.getUserType())) {
            BciOrganizerInfo bciOrganizerInfo = bciOrganizerInfoMapper.findOrganizerByUserId(usrInfo.getId());
            if (bciOrganizerInfo == null) {
                logger.warn("用户身份为主办方但是userId关联的主办方不存在= userId:{}", userId);
                throw new CustomBizException("该用户不是主办方");
            }
            map.put("organizerInfo", bciOrganizerInfo);
        }
        //如果是艺人
        if (Constant.ARTIST.equals(usrInfo.getUserType())) {
            BciArtistInfo bciArtistInfo = bciArtistInfoMapper.findArtistByUserId(userId);
            if (bciArtistInfo == null) {
                logger.warn("用户身份为艺人但是userId关联的艺人不存在= userId:{}", userId);
                throw new CustomBizException("该用户不是艺人");
            }
            map.put("artistInfo", bciArtistInfo);
            //查询艺人的粉丝的数量
            Integer focusCount = usrUserFocusArtistMapper.findCountByArtistId(bciArtistInfo.getId(), null);
            map.put("focusCount", focusCount);
        }
        if (Constant.FIELD_PROVIDER.equals(usrInfo.getUserType())) {
            BciFieldInfo bciFieldInfo = bciService.getField(userId);
            if (bciFieldInfo == null) {
                logger.warn("用户身份为艺人但是userId关联的场地不存在= userId:{}", userId);
                throw new CustomBizException("该用户不是场地");
            }
            map.put("bciFieldInfo", bciFieldInfo);
        }
        return map;
    }


    /**
     * 获取用户消息列表
     *
     * @param userId
     * @param type
     * @param page
     * @param count
     * @return
     */
    public List<Map<String, Object>> getUserMessageWebList(Integer userId, String type, Integer page, Integer count) {
        Integer start = (page - 1) * count;
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<UsrPersonalMessage> usrPersonalMessages = usrPersonalMessageMapper.getUsrPersonalMessageByUserIdAndType(userId, type, start, count);
        for (UsrPersonalMessage usrPersonalMessage : usrPersonalMessages) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("id", usrPersonalMessage.getId());//消息id
            resultMap.put("title", usrPersonalMessage.getTitle());//标题
            resultMap.put("time", usrPersonalMessage.getCreateTime());//时间
            if (usrPersonalMessage.getIsRead()) {
                resultMap.put("isRead", 1);
            } else {
                resultMap.put("isRead", 0);
            }
            resultList.add(resultMap);
        }
        //将user所有的信息 改为已读
        usrPersonalMessageMapper.updateIsQuery(userId);
        return resultList;
    }

    /**
     * 获取用户消息列表
     *
     * @param userId
     * @param type
     * @param page
     * @param count
     * @return
     */
    public List<Map<String, Object>> getUserMessageList(Integer userId, String type, Integer page, Integer count) {
        Integer start = (page - 1) * count;
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<UsrPersonalMessage> usrPersonalMessages = usrPersonalMessageMapper.getUsrPersonalMessageByUserIdAndType(userId, type, start, count);
        for (UsrPersonalMessage usrPersonalMessage : usrPersonalMessages) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("id", usrPersonalMessage.getId());//消息id
            resultMap.put("title", usrPersonalMessage.getTitle());//标题
            resultMap.put("time", usrPersonalMessage.getCreateTime());//时间
            resultMap.put("isRead", usrPersonalMessage.getIsRead() == true ? 1 : 0);//是否已读
            resultList.add(resultMap);
        }
        return resultList;
    }


    /**
     * 获取用户单个消息
     *
     * @param messageId
     * @param userId
     * @return
     */
    public Map<String, Object> getUserMessage(Integer messageId, Integer userId) {
        UsrPersonalMessage usrPersonalMessage = usrPersonalMessageMapper.selectByPrimaryKey(messageId);
        if (usrPersonalMessage != null && usrPersonalMessage.getUserId().equals(userId)) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("time", usrPersonalMessage.getCreateTime());
            resultMap.put("content", usrPersonalMessage.getContent());
            resultMap.put("title", usrPersonalMessage.getTitle());
            //修改该消息为已读
            UsrPersonalMessage updateUsrPersonalMessage = new UsrPersonalMessage();
            updateUsrPersonalMessage.setId(usrPersonalMessage.getId());
            updateUsrPersonalMessage.setIsRead(true);
            usrPersonalMessageMapper.updateByPrimaryKeySelective(usrPersonalMessage);
            return resultMap;
        }
        return null;
    }


    /**
     * 获取用户的第三方账号绑定情况
     *
     * @param userId
     * @return
     */
    public Map<String, Object> getUserBindThirdAccount(Integer userId) {
        Map<String, Object> resultMap = new HashMap<>();
        UsrThirdpartAccountInfo usrThirdpartAccountInfo = usrThirdpartAccountInfoMapper.findUsrThirdpartAccountInfoByUserId(userId);
        UsrInfo usrInfo = usrInfoMapper.selectByPrimaryKey(userId);
        resultMap.put("mobile", usrInfo.getMobile() != null ? usrInfo.getMobile() : "");//QQ
        if (usrThirdpartAccountInfo != null) {
            resultMap.put("weibo", usrThirdpartAccountInfo.getWeiboOpenid() != null ? 1 : 0);//微博
            resultMap.put("wechat", usrThirdpartAccountInfo.getWechatOpenid() != null ? 1 : 0);//微信
            resultMap.put("qq", usrThirdpartAccountInfo.getQqOpenid() != null ? 1 : 0);//QQ
        } else {
            resultMap.put("weibo", 0);//微博
            resultMap.put("wechat", 0);//微信
            resultMap.put("qq", 0);//QQ
        }
        return resultMap;
    }


    /**
     * 通过第三方账号登陆
     *
     * @param nickName
     * @param sex
     * @param headIcon
     * @param openId
     * @param thirdAccountType
     * @param lastAccessIp
     * @param type
     * @param deviceUniqueToken
     * @param messageToken
     * @param deviceCode
     * @param source
     * @param channel
     * @return
     */
    @Transactional
    public String loginByUserbindThirdAccount(String nickName, String sex, String headIcon, String openId, String thirdAccountType, String lastAccessIp, String type, String deviceUniqueToken, String messageToken, String deviceCode, String source, String channel) {
        UsrThirdpartAccountInfo usrThirdpartAccountInfo;
        Integer userId = null;
        if (QQ.equals(thirdAccountType)) {//如果是qq
            usrThirdpartAccountInfo = usrThirdpartAccountInfoMapper.findUsrThirdpartAccountInfoByOpenId(openId, thirdAccountType);
            if (usrThirdpartAccountInfo != null && openId.equals(usrThirdpartAccountInfo.getQqOpenid())) {//QQ openId吻合  已存在
                userId = usrThirdpartAccountInfo.getUserId();
            } else {
                userId = saveUsrInfo(null, nickName, sex, headIcon, null, source, channel, lastAccessIp).getId();//注册账号
                //绑定QQopenId
                saveUsrThirdpartAccount(userId, openId, null, null);
            }
        } else if (WEIBO.equals(thirdAccountType)) {//如果是微博
            usrThirdpartAccountInfo = usrThirdpartAccountInfoMapper.findUsrThirdpartAccountInfoByOpenId(openId, thirdAccountType);
            if (usrThirdpartAccountInfo != null && openId.equals(usrThirdpartAccountInfo.getWeiboOpenid())) {//微博openId吻合 已存在
                userId = usrThirdpartAccountInfo.getUserId();
            } else {
                userId = saveUsrInfo(null, nickName, sex, headIcon, null, source, channel, lastAccessIp).getId();//注册账号
                //绑定微博openId
                saveUsrThirdpartAccount(userId, null, openId, null);
            }
        } else if (WECHAT.equals(thirdAccountType)) {//如果是微信
            usrThirdpartAccountInfo = usrThirdpartAccountInfoMapper.findUsrThirdpartAccountInfoByOpenId(openId, thirdAccountType);
            if (usrThirdpartAccountInfo != null && openId.equals(usrThirdpartAccountInfo.getWechatOpenid())) {//微信openId吻合 已存在
                userId = usrThirdpartAccountInfo.getUserId();
            } else {
                userId = saveUsrInfo(null, nickName, sex, headIcon, null, source, channel, lastAccessIp).getId();//注册账号
                //绑定微信openId
                saveUsrThirdpartAccount(userId, null, null, openId);
            }
        }
        if (CommonValidator.isStringsNotNull(userId)) {
            return createToken(type, deviceUniqueToken, userId, messageToken, deviceCode);
        }
        return null;
    }


    /**
     * 绑定第三方账号
     *
     * @param userId
     * @param openId
     * @param thirdAccountType
     * @return
     */
    @Transactional
    public boolean bindThirdAccount(Integer userId, String openId, String thirdAccountType) {
        UsrThirdpartAccountInfo usrThirdpartAccountInfo = usrThirdpartAccountInfoMapper.findUsrThirdpartAccountInfoByUserId(userId);
        if (usrThirdpartAccountInfo == null) {//如果之前没有绑定过第三方账号
            usrThirdpartAccountInfo = new UsrThirdpartAccountInfo();
        }
        if (QQ.equals(thirdAccountType)) {//如果是qq
            UsrThirdpartAccountInfo usrThirdpartAccountInfo1 = usrThirdpartAccountInfoMapper.findUsrThirdpartAccountInfoByOpenId(openId, thirdAccountType);
            if (usrThirdpartAccountInfo1 != null) {
                return false;
            }
            usrThirdpartAccountInfo.setQqOpenid(openId);
            usrThirdpartAccountInfo.setQqBuddleTime(new Date());
        } else if (WEIBO.equals(thirdAccountType)) {//如果是微博
            UsrThirdpartAccountInfo usrThirdpartAccountInfo1 = usrThirdpartAccountInfoMapper.findUsrThirdpartAccountInfoByOpenId(openId, thirdAccountType);
            if (usrThirdpartAccountInfo1 != null) {
                return false;
            }
            usrThirdpartAccountInfo.setWeiboOpenid(openId);
            usrThirdpartAccountInfo.setWeiboBuddleTime(new Date());
        } else if (WECHAT.equals(thirdAccountType)) {//如果是微信
            UsrThirdpartAccountInfo usrThirdpartAccountInfo1 = usrThirdpartAccountInfoMapper.findUsrThirdpartAccountInfoByOpenId(openId, thirdAccountType);
            if (usrThirdpartAccountInfo1 != null) {
                return false;
            }
            usrThirdpartAccountInfo.setWechatOpenid(openId);
            usrThirdpartAccountInfo.setWechatBuddleTime(new Date());
        }
        Integer count;
        if (usrThirdpartAccountInfo.getId() == null) {
            usrThirdpartAccountInfo.setUserId(userId);
            count = usrThirdpartAccountInfoMapper.insertSelective(usrThirdpartAccountInfo);//新添加一条
        } else {
            count = usrThirdpartAccountInfoMapper.updateByPrimaryKeySelective(usrThirdpartAccountInfo);
        }
        return count > 0 ? true : false;
    }

    /**
     * 保存第三方账户
     *
     * @param userId
     * @param qqOpenId
     * @param weiboOpenId
     * @param wechaatOpenId
     * @return
     */
    @Transactional
    public Boolean saveUsrThirdpartAccount(Integer userId, String qqOpenId, String weiboOpenId, String wechaatOpenId) {
        //绑定openId
        UsrThirdpartAccountInfo usrThirdpartAccountInfo = new UsrThirdpartAccountInfo();
        usrThirdpartAccountInfo.setUserId(userId);

        usrThirdpartAccountInfo.setQqOpenid(qqOpenId);
        usrThirdpartAccountInfo.setQqBuddleTime(qqOpenId == null ? null : new Date());

        usrThirdpartAccountInfo.setWechatOpenid(wechaatOpenId);
        usrThirdpartAccountInfo.setWechatBuddleTime(wechaatOpenId == null ? null : new Date());

        usrThirdpartAccountInfo.setWeiboOpenid(weiboOpenId);
        usrThirdpartAccountInfo.setWeiboBuddleTime(weiboOpenId == null ? null : new Date());

        Integer count = usrThirdpartAccountInfoMapper.insertSelective(usrThirdpartAccountInfo);
        return count > 0 ? true : false;
    }

    /**
     * 记录短信
     */
    @Transactional
    public void saveUsrSendSmsLog(String phone, String captcha) {
        usrSendSmsLogMapper.updateUsrSendSmsLogIsNewByMobile(phone);//将该手机之前的号码短信设置为false
        //储存手机
        UsrSendSmsLog usrSendSmsLog1 = new UsrSendSmsLog();
        usrSendSmsLog1.setCreateTime(new Date());
        usrSendSmsLog1.setIsNew(true);
        usrSendSmsLog1.setMobile(phone);
        usrSendSmsLog1.setValidCode(captcha);
        usrSendSmsLogMapper.insertSelective(usrSendSmsLog1);
    }


    /**
     * 查询是否有消息（关注，点赞，系统,个人）
     *
     * @return
     */
    public Map<String, Object> findMessageCount(Integer userId) {
        BciArtistInfo bciArtistInfo = bciArtistInfoMapper.findArtistByUserId(userId);
        Integer focusCount = 0;
        Integer optCount = 0;
        //如果是艺人
        if (bciArtistInfo != null) {
            //有关注
            focusCount = usrUserFocusArtistMapper.findCountByArtistIdAndLastDate(bciArtistInfo.getId(), bciArtistInfo.getLastFocusTime());
            List<Integer> messageIds = samArtistMessageMapper.findMessageIdByArtistId(bciArtistInfo.getId());//根据艺人id查询所有的消息ID
            if (messageIds.size() != 0) {
                //是否有点赞
                optCount = usrSharedMessageOptInMapper.findOptCountByArtistId(messageIds, bciArtistInfo.getLastOptTime());
            }
        }
        //查询是否有未被查询的新的系统信息
        Integer sysMessageCount = usrPersonalMessageMapper.getMessageCountByUserIdAndType(userId, Constant.SYS);
        //查询是否未被查询的个人信息
        Integer messageCount = usrPersonalMessageMapper.getMessageCountByUserIdAndType(userId, Constant.PRIVATE);
        Map<String, Object> resuletMap = new HashMap<>();
        resuletMap.put("focusCount", focusCount);
        resuletMap.put("optCount", optCount);
        resuletMap.put("sysMessageCount", sysMessageCount);
        resuletMap.put("status", 0);
        resuletMap.put("messageCount", messageCount);
        if (focusCount > 0 || optCount > 0 || sysMessageCount > 0 || messageCount > 0) {
            resuletMap.put("status", 1);
        }
        return resuletMap;
    }


    /**
     * 查询检票员的手机号是否正常
     *
     * @param mobile
     * @return
     */
    public UsrTicketInspector findMoblie(String mobile) {
        return usrTicketInspectorMapper.findUsrTicketInspectorByMobile(mobile);
    }


    /**
     * 保存微信账号信息 true为 成功  false 已存在
     *
     * @param unionId
     * @param headIcon
     * @param nickName
     * @param sex
     * @return
     */
    public boolean saveUsrWechat(String unionId, String headIcon, String nickName, String sex) {
        UsrWechat usrWechat = usrWechatMapper.findUnionId(unionId);
        if (usrWechat == null) {
            usrWechat = new UsrWechat();
            usrWechat.setCreateTime(new Date());
            usrWechat.setHeadIcon(headIcon);
            usrWechat.setNickName(nickName);
            usrWechat.setSex(sex);
            usrWechat.setUnionId(unionId);
            usrWechatMapper.insertSelective(usrWechat);
            return true;
        }
        return false;
    }

    public boolean save(String unionId, String headIcon, String nickName, String sex) {
        UsrWechat usrWechat = usrWechatMapper.findUnionId(unionId);
        if (usrWechat == null) {
            usrWechat = new UsrWechat();
            usrWechat.setCreateTime(new Date());
            usrWechat.setHeadIcon(headIcon);
            usrWechat.setNickName(nickName);
            usrWechat.setSex(sex);
            usrWechat.setUnionId(unionId);
            usrWechatMapper.insertSelective(usrWechat);
            return true;
        }
        return false;
    }

}

